
#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
#include "ESP8266WiFi.h"
#include <MQTT.h>
#include "WifiUDP.h"
#include "NTPClient.h"
#include "TimeLib.h"
#include <Ticker.h>

const char* ssid = "Wi-Fi SSID";      // Wi-Fi SSID
const char* password = "XXXXXXXX";    // Wi-Fi Password

// MQTT info
const char* hostname = "m14.cloudmqtt.com";
int port = 13536;
const char* user = "xxxx";
const char* user_password = "xxxx";
const char* id = "watch";

SSD1306Wire  display(0x3C, 4, 5);

int buttons[3] = {12, 13, 14};
int buttons_count[3] = {0,};

WiFiClient net;
MQTTClient client;

WiFiUDP udp;

// You can specify the time server pool, the offset (in seconds) 
// and the update interval (in milliseconds).
// Set the offset based on your timezone, for example, UTC+8
NTPClient ntp(udp, "pool.ntp.org", 60 * 60 * 8, 60000);

Ticker ticker;
volatile int ticker_interrupt = 0;

void tick() {
  ticker_interrupt = 1;
}

void connect() {
  if (WiFi.status() != WL_CONNECTED) {
    return;
  }

  Serial.println("connecting to MQTT...");
  if (!client.connect(id, user, user_password)) {
    return;
  }

  Serial.println("\nconnected!");

  client.subscribe("/hello");
  // client.unsubscribe("/hello");
}

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);
}

void setup() {
  Serial.begin(115200);
  Serial.println("\nWatch");
  
  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 0, "Watch");
  display.display();

  Serial.println("Connecting to Wi-Fi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected");

  ntp.begin();

  client.begin(hostname, port, net);
  client.onMessage(messageReceived);

  Serial.println("connecting to MQTT...");
  while (!client.connect(id, user, user_password)) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("\nconnected!");

  client.subscribe("/relay");

  ticker.attach(1, tick);

  for (int i=0; i<3; i++) {
    pinMode(buttons[i], INPUT);
  }
}

void loop() {
  client.loop();

  if (!client.connected()) {
    connect();
  }

  if (ticker_interrupt) {
    ticker_interrupt = 0;
    ntp.update();
    time_t t = ntp.getEpochTime();
    setTime(t);
    String date = "";
    date += year();
    date += "-";
    date += month();
    date += "-";
    date += day();
    
    Serial.println(date);
    Serial.println(ntp.getFormattedTime());
    display.clear();
    display.drawString(0, 0, date);
    display.drawString(0, 26, ntp.getFormattedTime());
    display.display();
  }

  for (int i=0; i<3; i++) {
    if (digitalRead(buttons[i]) == LOW) {
      if (buttons_count[i] == 0) {
        buttons_count[i] = millis();
      } else if (buttons_count[i] > 0) {
        if ((millis() - buttons_count[i]) > 10) {
          buttons_count[i] = -1;
          
          Serial.print(i + 1);
          Serial.println(" button is pressed");
          if (i == 0) {
            client.publish("/relay", "on", 0, 1);
          } else if (i == 1) {
            client.publish("/relay", "off", 0, 1);
          }
        }
      }
    } else {
      buttons_count[i] = 0;
    }
  }
  
}
